home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
-
- /* --------------------------------------------------------------------
- Module: WHICHARC.C
- Subject: tries to determine the archiver used to compress files
- Author: Heinz Ozwirk & David Gersic
- modified for SNIPPETS by Bob Stout
- Status: public domain
- Started: 28.09.1991 13:35:57
- Modified: 13.10.1991 14:15:57
- Modified: 5 January, 1992 11:50am by David Gersic
- Added return codes for self extracting archive files.
- Modified: 16 January, 1992, 4:15pm by David Gersic
- Added Pak and ARC ver. 6 with information from Richard
- Vanhouten @1:272/38. I'm not sure that this code works
- perfectly for those formats, as his message seems to
- indicate that the entire archive has to be scanned for
- headers to check before the type can be perfectly
- determined. It seems to work for test archives produced
- here, but may not work for all archives.
- --------------------------------------------------------------------
- Prototype: int WhichArc(char *pName)
- pName address of full path name of file to examine
- Result -1: file not found
- UNKNOWN: unknown packer
- ARC: ARC or PKARC
- ARJ: ARJ
- LHA: LHARC or LHA
- ZIP: PKZIP
- ZOO: Zoo
- PAK: Pak
- ARC7: ARC later than ver. 6.02
- SFXARC: Self Extracting PKARC
- SFXARJ: Self Extracting ARJ
- SFXLHARC:Self Extracting LHARC
- SFXLHA: Self Extracting LHA
- SFXZIP: Self Extracting ZIP
- SFXPAK: Self Extracting Pak
- SFXARC6: Self Extracting ARC later than ver. 6.02
- EXE: MS DOS executable of unknown type
-
- LHARC/LHA
- No archive header. WhichArc examines the checksum of the first
- file header. If the checksum is valid and if the string -lh?-
- is found, LHA or LHARC is assumed.
-
- ARJ
- If a file starts with 0x60, 0xEA, ARJ is assumed.
-
- ZIP
- If the file begins with "PK", PKZIP is assumed.
-
- ZOO
- Zoo'ed archives always start with "ZOO x.xx Archive". WhichArc
- only looks for "ZOO".
-
- ARC
- No header. Files starting with 0x1A are assumed to be ARCed.
-
- PAK
- Similar to ARC files, but if the second byte of the header is 0x0a or
- 0x0b, it was created by Pak.
-
- ARC7
- Similar to ARC, but if the second byte of the header is 0x14 or
- higher, it was created by an Arc version later than 6.02.
-
- SFX*
- All of the SFX files start with a small decompressor. Seek past
- the decompressor and repeat the above checks.
- -------------------------------------------------------------------- */
-
-
- typedef unsigned char BYTE;
-
- enum ArcType { ArcERR=-1, UNKNOWN, ARC, ZOO, ARJ, LHARC, LHA, ZIP, PAK, ARC7,
- SFXARC, SFXARJ, SFXLHARC, SFXLHA, SFXZIP, SFXARC7, SFXPAK, EXE
- };
-
- enum ArcType WhichArc(char *pName)
- {
- FILE *fp;
- BYTE header[128];
- int c, i, n;
- enum ArcType retval = ArcERR;
-
- memset(header, 0, sizeof(header));
- fp = fopen(pName, "rb");
- if (fp == NULL)
- goto EXIT; /* error opening file */
- n = fread(header, sizeof(BYTE), sizeof(header) - sizeof(BYTE), fp);
-
- if (n <= 0) /* error reading from file */
- goto EXIT;
-
- if (n >= 7 && n >= header[0] + 2)
- {
- for (c = 0, i = header[0]; i--; c += (header+2)[i])
- ;
- if (((BYTE)(c & 0x00FF)) == header[1]
- && header[2] == '-'
- && header[3] == 'l'
- && header[4] == 'h'
- && header[6] == '-')
- {
- retval = (header[5] > '1') ? LHA : LHARC;
- goto EXIT;
- }
- }
-
- if (n >= 2)
- {
- if (header[0] == 0x60 && header[1] == 0xEA)
- {
- retval = ARJ;
- goto EXIT;
- }
- if (header[0] == 'P' && header[1] == 'K')
- {
- retval = ZIP;
- goto EXIT;
- }
- }
-
- if (n >= 3 && header[0] == 'Z' && header[1] == 'O' && header[2] == 'O')
- {
- retval = ZOO;
- goto EXIT;
- }
-
- if (n >= 25 && header[0] == 0x1A)
- {
- if (header[1]>0x14)
- retval = ARC7;
- else if (header[1]==0x0a || header[1]==0x0b)
- retval = PAK;
- else retval = ARC;
- goto EXIT;
- }
-
- if (0 == strncmp(header, "MZ", 2)) /* some sort of .EXE file */
- {
- /* test for SFX ARJ file */
-
- memset(header, 0, sizeof(header));
- fseek(fp, 0x39ba, SEEK_SET);
- n = fread(header, sizeof(BYTE),
- sizeof(header) - sizeof(BYTE), fp);
- if (n > 1 && header[0] == 0x60 && header[1] == 0xea)
- {
- retval = SFXARJ;
- goto EXIT;
- }
-
- /* test for SFX LHARC file */
-
- memset(header, 0, sizeof(header));
- fseek(fp, 0x653, SEEK_SET);
- n = fread(header, sizeof(BYTE),
- sizeof(header) - sizeof(BYTE), fp);
- for (c = 0, i = header[0]; i--; c += (header+2)[i])
- ;
- if (n >= 7 && n >= header[0] + 2)
- {
- if (((BYTE)(c & 0x00FF)) == header[1]
- && header[2] == '-'
- && header[3] == 'l'
- && header[4] == 'h'
- && header[6] == '-')
- {
- retval = SFXLHARC;
- goto EXIT;
- }
- }
-
- /* test for SFX LHA file */
-
- memset(header, 0, sizeof(header));
- fseek(fp, 0x799, SEEK_SET);
- n = fread(header, sizeof(BYTE),
- sizeof(header) - sizeof(BYTE), fp);
- for (c = 0, i = header[0]; i--; c += (header+2)[i])
- ;
- if (n >= 7 && n >= header[0] + 2)
- {
- if (((BYTE)(c & 0x00FF)) == header[1]
- && header[2] == '-'
- && header[3] == 'l'
- && header[4] == 'h'
- && header[6] == '-')
- {
- retval = SFXLHA;
- goto EXIT;
- }
- }
-
- /* test for SFX ZIP file */
-
- memset(header, 0, sizeof(header));
- fseek(fp, 0x31f0, SEEK_SET);
- n = fread(header, sizeof(BYTE),
- sizeof(header) - sizeof(BYTE), fp);
- if (n > 1 && header[0] == 'P' && header[1] == 'K')
- {
- retval = SFXZIP;
- goto EXIT;
- }
-
- /* test for SFX PKARC file */
-
- memset(header, 0, sizeof(header));
- fseek(fp,0x261e,SEEK_SET);
- n = fread(header, sizeof(BYTE),
- sizeof(header) - sizeof(BYTE), fp);
- if (n > 1 && header[0] == 0x1a)
- {
- if (header[1]>0x14)
- retval = SFXARC7;
- else if (header[1]==0x0a || header[1]==0x0b)
- retval = SFXPAK;
- else retval = SFXARC;
- }
- else retval = EXE;
- }
- retval = UNKNOWN;
- EXIT: fclose(fp);
- return retval;
- }
-
- #ifdef TEST
-
- int main(int argc,char *argv[])
- {
- char *arc_types[]={"UNKNOWN", "ARC", "ZOO", "ARJ", "LHARC", "LHA",
- "ZIP", "PAK", "PAK", "ARC7", "SFXARC", "SFXARJ",
- "SFXLHARC", "SFXLHA", "SFXZIP", "SFXARC7", "SFXPAK",
- "EXE"};
-
- while (--argc)
- {
- enum ArcType which;
-
- if (ArcERR == (which = WhichArc(*++argv)))
- printf("File error accessing %s\n", *argv);
- else printf("%s archive type is %s\n", *argv, arc_types[which]);
- }
- return(0);
- }
-
- #endif
-